package ws

import (
	"errors"
	"github.com/nntaoli-project/goex"
	"github.com/nntaoli-project/goex/builder"
	"log"
	"strings"
	"sync"
)

type HandelPrice func(trade * goex.Trade)
type SubscribePriceStruct struct {
	Exchange string
	Symbol string
	ContractType string
	tradeCalFn  func(trade *goex.Trade, contract string)
	Ws goex.FuturesWsApi

	mapLock   sync.RWMutex
	StrategyMap map[string]HandelPrice
}
var DefaultCallBack =func(trade *goex.Trade, contract string) {
	log.Println(trade)
}

//创建一个订阅
func NewSubPrice(exchange string, contractType string, symbol string) SubscribePriceStruct {
	sub :=SubscribePriceStruct{
		Exchange: exchange,
		Symbol: symbol,
		ContractType: contractType,
		StrategyMap: make(map[string]HandelPrice),
	}
	return sub
}

//订阅价格
func (s *SubscribePriceStruct)SubscribePrice() error{
	Ws, err := builder.NewAPIBuilder().BuildFuturesWs(s.Exchange)
	if err != nil{
		log.Println(err)
		return err
	}
	s.tradeCalFn = func(trade *goex.Trade, contract string) {
		s.mapLock.Lock()
		for _,handelPrice :=range s.StrategyMap{

			//switch strategy.(type) {
			//	case *strategies.StrategyWildFluctuation:
			//		v := strategy.(*strategies.StrategyWildFluctuation)
			//		v.HandlePrice(trade)
			//}
			handelPrice(trade)
			//nameValue := v.FieldByName("Exchange")
			//fmt.Println(nameValue)
			//fmt.Println(v.Elem().CanSet())
			//var args = []reflect.Value{reflect.ValueOf(trade)}
			//method := v.MethodByName("HandlePrice")
			//fmt.Println(method.Elem().CanSet())
			//method.Call(args)
		}
		s.mapLock.Unlock()
	}
	Ws.TradeCallback(s.tradeCalFn)
	pairs := strings.Split(s.Symbol,"_")
	currencyA := goex.NewCurrency(pairs[0],"")
	currencyB := goex.NewCurrency(pairs[1],"")
	pair := goex.NewCurrencyPair(currencyA,currencyB)
	Ws.SubscribeTrade(pair,s.ContractType)
	s.Ws = Ws
	return nil
}

//取消订阅价格
func (s *SubscribePriceStruct)UnSubscribePrice() error{
	if s.Ws !=nil{
		s.Ws.Unsubscribe()
	}else {
		return errors.New("还没有订阅数据")
	}
	return nil
}

// 设置回调函数
func (s *SubscribePriceStruct) TradeCallback(f func(trade *goex.Trade, contract string)) {
	s.tradeCalFn = f
	s.Ws.TradeCallback(s.tradeCalFn)
}

//添加策略
func (s *SubscribePriceStruct)AddStrategy(strategyKey string,f HandelPrice){
	s.mapLock.Lock()
	//switch strategy.(type) {
	//case *strategies.StrategyWildFluctuation:
	//	v := strategy.(*strategies.StrategyWildFluctuation)
	//	accountName := v.AccountName
	//	strategyName := v.StrategyName
	//	strategyKey := fmt.Sprintf("%s_%s",strategyName,accountName)
	//	s.StrategyMap[strategyKey] = strategy
	//}
	s.StrategyMap[strategyKey] =f

	s.mapLock.Unlock()
}

//删除策略
func (s *SubscribePriceStruct)DelStrategy(strategyKey string){
	s.mapLock.Lock()
	if _,ok := s.StrategyMap[strategyKey];ok{
		delete(s.StrategyMap, strategyKey)
	}
	s.mapLock.Unlock()
}